#include "compare.h"

#include <cstdio>
#include <sys/wait.h>
#include <unistd.h>
#include <cstdlib>
#include <cctype>

int compare_zoj(const char *file1, const char *file2);


//int compare_diff(const char *file1,const char *file2)
//{
//    char diff[1024];
//    sprintf(diff,"diff -q -B -b -w --strip-trailing-cr %s %s", file1, file2);
//    int d = system(diff);
//    if (d) return OJ_WA;
//    sprintf(diff,"diff -q -B --strip-trailing-cr %s %s", file1, file2);
//    int p = system(diff);
//    if (p) return OJ_PE;
//    else return OJ_AC;
//}

int compare(const char *file1, const char *file2)
{
    return compare_zoj(file1, file2);
}

int compare_diff_spj(const char* spj_exe, const char* file1, const char* file2, const char* file3)
{
    int pid = fork();
    if(pid == 0)
    {
        execl(spj_exe, spj_exe, file1, file2, file3, NULL);
        exit(-1);
    }
    else if(pid > 0)
    {
        int status;
        waitpid(pid, &status, 0);
        int8_t ret = WEXITSTATUS(status);
        if(ret == -1) return OJ_SPJ_ERR;
        else if(ret == 0) return OJ_AC;
        else return OJ_WA;
    }
    else
    {
        return OJ_SPJ_ERR;
    }
}

int compare_spj(const char* spj_exe, const char* file1, const char* file2, const char* file3)
{
    return compare_diff_spj(spj_exe, file1, file2, file3);
}

void find_next_nonspace(int &c1, int &c2, FILE *&f1, FILE *&f2, int &ret)
{
    // Find the next non-space character or \n.
    while ((isspace(c1)) || (isspace(c2)))
    {
        if (c1 != c2)
        {
            if (c2 == EOF)
            {
                do
                {
                    c1 = fgetc(f1);
                } while (isspace(c1));
                continue;
            }
            else if (c1 == EOF)
            {
                do
                {
                    c2 = fgetc(f2);
                } while (isspace(c2));
                continue;
#ifdef IGNORE_ESOL
                }
            else if (isspace(c1) && isspace(c2))
            {
                while (c2 == '\n' && isspace(c1) && c1 != '\n')
                    c1 = fgetc(f1);
                while (c1 == '\n' && isspace(c2) && c2 != '\n')
                    c2 = fgetc(f2);

#else
            }
            else if ((c1 == '\r' && c2 == '\n'))
            {
                c1 = fgetc(f1);
            }
            else if ((c2 == '\r' && c1 == '\n'))
            {
                c2 = fgetc(f2);
#endif
            }
            else
            {
                ret = OJ_PE;
            }
        }
        if (isspace(c1))
        {
            c1 = fgetc(f1);
        }
        if (isspace(c2))




        {
            c2 = fgetc(f2);
        }
    }
}


int compare_zoj(const char *file1, const char *file2)
{
    int ret = OJ_AC;
    int c1, c2;
    FILE *f1, *f2;
    f1 = fopen(file1, "re");
    f2 = fopen(file2, "re");
    if (!f1 || !f2)
    {
        ret = OJ_RE;
    }
    else
        for (;;)
        {
            // Find the first non-space character at the beginning of line.
            // Blank lines are skipped.
            c1 = fgetc(f1);
            c2 = fgetc(f2);
            find_next_nonspace(c1, c2, f1, f2, ret);
            // Compare the current line.
            for (;;)
            {
                // Read until 2 files return a space or 0 together.
                while ((!isspace(c1) && c1) || (!isspace(c2) && c2))
                {
                    if (c1 == EOF && c2 == EOF)
                    {
                        goto end;
                    }
                    if (c1 == EOF || c2 == EOF)
                    {
                        break;
                    }
                    if (c1 != c2) {
                        // Consecutive non-space characters should be all exactly the ifconfig|grep 'inet'|awk -F: '{printf $2}'|awk  '{printf $1}'same
                        ret = OJ_WA;
                        goto end;
                    }
                    c1 = fgetc(f1);
                    c2 = fgetc(f2);
                }
                find_next_nonspace(c1, c2, f1, f2, ret);
                if (c1 == EOF && c2 == EOF)
                {
                    goto end;
                }
                if (c1 == EOF || c2 == EOF)
                {
                    ret = OJ_WA;
                    goto end;
                }

                if ((c1 == '\n' || !c1) && (c2 == '\n' || !c2))
                {
                    break;
                }
            }
        }
    end:
    if (f1)
        fclose(f1);
    if (f2)
        fclose(f2);
    return ret;
}